package services

import (
	"fmt"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
	"rest/model"
	"rest/until"
	"rest/usedb/MysqlConnect"
	"strconv"
	"time"
)

type Result struct {
	Code    int         `json:"code"`
	Success bool        `json:"success"`
	Msg     string      `json:"msg"`
	Data    interface{} `json:"data"`
}

//var sucresult = Result{
//	Code:    200,
//	Success: true,
//	Msg:     "请求成功",
//	Data:    nil,
//}
//var errresult = Result{
//	Code:    200,
//	Success: false,
//	Msg:     "请求失败",
//	Data:    nil,
//}

// 登录首页方法
// todo 登录的token尚未进行比较判断
func Login(c *gin.Context) {
	var result = Result{
		Code:    200,
		Success: true,
		Msg:     "请求成功",
		Data:    nil,
	}
	db := MysqlConnect.InitDB()
	defer db.Close()
	// 定义用户结构体
	type Login struct {
		Username string `form:"username" json:"username" binding:"required"`
		Password string `form:"password" json:"password" binding:"required"`
		Auth     string `form:"auth" json:"auth"`
		Token    string `form:"token" json:"token"`
	}
	var json Login
	if err := c.ShouldBind(&json); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	var loginUser Login
	selectSqlstr := fmt.Sprintf("SELECT username,password,auth,ass_token FROM user WHERE username = '%s' AND password = '%s'", json.Username, json.Password)
	_ = db.QueryRow(selectSqlstr).Scan(&loginUser.Username, &loginUser.Password, &loginUser.Auth, &loginUser.Token)
	if loginUser.Username == "" {
		result.Msg = "用户名或密码错误"
		c.JSON(http.StatusOK, result)
		return
	}
	if loginUser.Token == "" {
		ass_token := until.RandToken(99)
		updateSql := fmt.Sprintf("UPDATE user SET ass_token='%s' WHERE (`username`='%s') LIMIT 1", ass_token, loginUser.Username)
		_, _ = db.Exec(updateSql)
		result.Data = gin.H{
			"ass_token": ass_token,
		}
	}
	result.Data = gin.H{
		"ass_token": loginUser.Token,
	}
	c.JSON(http.StatusOK, result)
	return
}

type Alluser struct {
	Username string      `json:"username"`
	Name     string      `json:"name"`
	Gender   string      `json:"gender"`
	Phone    string      `json:"phone"`
	Auth     string      `json:"auth"`
	Active   interface{} `json:"active"`
	Email    string      `json:"email"`
}

// 获取用户列表方法
func ReturnUserList(c *gin.Context) {
	db := MysqlConnect.InitDB()
	defer db.Close()
	sqlStr := "SELECT username, name, gender, phone, auth, active, email FROM user"
	rows, _ := db.Query(sqlStr)
	var alluser Alluser
	var ss = []interface{}{}
	for rows.Next() {
		_ = rows.Scan(&alluser.Username, &alluser.Name, &alluser.Gender, &alluser.Phone, &alluser.Auth, &alluser.Active, &alluser.Email)
		if alluser.Auth == "0" {
			alluser.Active = true
		} else {
			alluser.Active = false
		}
		switch alluser.Auth {
		case "0":
			alluser.Auth = "管理员"
		case "1":
			alluser.Auth = "评委"
		case "2":
			alluser.Auth = "学生"
		}
		ss = append(ss, alluser)
	}
	var result = Result{
		Code:    200,
		Success: true,
		Msg:     "请求成功",
		Data:    nil,
	}
	result.Data = ss
	c.JSON(200, result)
}

// 获取邮箱验证码方法
type CodeRequest struct {
	Email string `form:"email" json:"email" binding:"required"`
}

func ReturnEmailCode(c *gin.Context) {
	var result = new(Result)
	*result = Result{
		Code:    200,
		Success: true,
		Msg:     "请求成功",
		Data:    nil,
	}
	var request CodeRequest
	if err := c.ShouldBind(&request); err != nil {
		result.Success = false
		result.Msg = "请求失败"
		c.JSON(200, result)
		return
	}
	code := until.SendCodeEmail(request.Email)
	var insertData1 model.EmailCode = model.EmailCode{
		Id:         0,
		Email:      request.Email,
		Code:       code,
		CreateTime: time.Time{},
	}
	db, _ := MysqlConnect.XormInitDB()
	defer db.Close()
	// 这里应该是更新，不该是插入
	sql_text := fmt.Sprintf("select email from email_code where email = '%s'", request.Email)
	data, _ := db.Query(sql_text)
	if len(data) > 0 {
		create_time := fmt.Sprintf("%s-%s-%s %s:%s:%s", strconv.Itoa(time.Now().Year()), strconv.Itoa(int(time.Now().Month())), strconv.Itoa(time.Now().Day()), strconv.Itoa(time.Now().Hour()), strconv.Itoa(time.Now().Minute()), strconv.Itoa(time.Now().Second()))
		update_text := fmt.Sprintf("update email_code set code = '%s',create_time = '%v'", insertData1.Code, create_time)
		_, _ = db.Query(update_text)
	} else {
		i, e := db.Insert(&insertData1)
		fmt.Println(i, e)
	}

	c.JSON(http.StatusOK, result)
	return
}

// 邮箱验证码登录方法

type LoginByEmailRequest struct {
	Email  string `form:"email" json:"email" binding:"required"`
	Vacode string `form:"vacode" json:"vacode" binding:"required"`
}

func LoginByEmail(c *gin.Context) {
	var result Result
	var json LoginByEmailRequest
	// 参数校验
	if err := c.ShouldBind(&json); err != nil {
		c.JSON(400, err.Error())
	}
	db, _ := MysqlConnect.XormInitDB()
	defer db.Close()
	sql_text := fmt.Sprintf("select code from email_code where email='%s' order by create_time desc limit 1", json.Email)
	data, err := db.Query(sql_text)
	if err != nil {
		panic(err)
	}
	for _, v := range data {
		// 查询数据库中的验证码
		db_code := fmt.Sprintf("%s", v["code"])
		if json.Vacode != db_code {
			result.Code = 401
			result.Msg = "验证码错误"
			result.Success = false
			c.JSON(http.StatusOK, result)
			return
		}
		ass_token := until.RandToken(99)
		result.Code = 200
		result.Msg = "登陆成功"
		result.Success = true
		result.Data = gin.H{
			"ass_token": ass_token,
		}
		c.JSON(http.StatusOK, result)
		return
	}

}

func Test(c *gin.Context) {
	c.JSON(200, gin.H{
		"message": "hello world",
	})
}

// 删除指定用户
type Deluser struct {
	Username string `json:"username"`
}

func DelUser(c *gin.Context) {
	fmt.Println()
	var data = Deluser{}
	err := c.ShouldBind(&data)
	if err != nil {
		c.JSON(http.StatusOK, Result{
			Code:    0,
			Success: false,
			Msg:     "请输入正确参数",
			Data:    nil,
		})
		return
	}
	sql := fmt.Sprintf("delete from user where username='%s'", data.Username)
	fmt.Println(sql)
	db := MysqlConnect.InitDB()
	defer db.Close()
	_, err = db.Exec(sql)
	if err != nil {
		fmt.Println("删除失败")
		c.JSON(http.StatusOK, Result{
			Code:    0,
			Success: false,
			Msg:     "删除失败",
			Data:    nil,
		})
		return
	}
	c.JSON(http.StatusOK, Result{
		Code:    0,
		Success: true,
		Msg:     "删除成功",
		Data:    nil,
	})
	return
}
